#!/usr/bin/python3
# -*- coding: UTF-8 -*- 
# 设置utf-8  显示中文
"""
@Author: guo
@File：get_file_path.py
"""
import sys
import os
import re

sys.path.append("../../")
from config.get_conf_data import GetConfData


class GetFilePath:
    """操作文件,文件的拼接,更改文件类型等"""

    def __init__(self):
        self.__conf = GetConfData()
        self.__slash = self.__conf.get_slash_value()
        self.__backslash = self.__conf.get_backslash_value()
        # yml 文件的顶层目录的路径
        self.__ymlfilepath = self.__conf.get_ymlfile_path()
        # yml 文件的顶层目录的名称,如data或 request_data目录。
        self.__ymldirname = self.__conf.get_yml_dir()
        # jsonfile 文件的顶层目录的路径
        self.__jsonfilepath = self.__conf.get_jsonfile_path()
        # jsonfile 文件的顶层目录的名称,如jsonfile
        self.__jsonfilename = self.__conf.get_jsonfile_dir()

    # def get_file_abspath_yml(self,filedir,filename:str):
    #     """拼接yml文件的绝对路径"""
    #     """
    #     此处还可以做的更加智能,来检测filename里,是否包括了yml文件的顶层目录 也就是data目录.
    #     因为data目录是不需要写的.传入的filedir已经包括了data目录.
    #     也就是说 可以对拼接后的路径进行检测文件是否存在,当不存在时,再检测filename里是否包括了"data/"
    #     当以 data/ 开头时,表示写多了.此时使用lstrip()进行去掉.然后再次进行拼接.
    #     对拼接后的结果再次进行检测.若文件存在,则返回该值,不存在,则返回None
    #     """
    #     # 去掉开头和结尾的(反)斜杠
    #     filename = self.__check_filename(filename)
    #     py_str = ".py"
    #     yml_str = ".yml"
    #     # 为了防止将yml文件写成了py文件,所以要先将py文件替换为yml文件
    #     # 因为casee yml文件的名称与case py文件的名称是一致的.
    #     if filename.endswith(py_str) :
    #         filename =filename.rstrip(py_str)
    #     # 检查文件后缀
    #     filename = filename if filename.endswith(yml_str) else filename+yml_str
    #     # 拼接文件路径
    #     filepath = os.path.abspath(os.path.join(filedir,filename))
    #     return filepath

    def get_file_abspath_yml(self, filepathname: str):
        """
        1:拼接yml文件的绝对路径
        2:filepathname: yml文件的名称，包括路径。但不包含ymlfile所在的目录。如 demo/test_data.yml，而不是ymlfile/demo/test_data.yml
        3:在检测filepathname时，当以/ 或 \\ 开头或结尾时，则直接去掉这些 / 或\\
        4:然后再检测filename 是否以 yml文件的顶层目录，如ymlfile进行开头，如 ymlfile/ 或 ymlfile\\
        5:当以 yml文件的顶层目录进行开头时，则直接去掉。因为在拼接时，会自动加上顶层目录。
        6:对拼接后的结果，文件是否存在，先不进行验证。
        """

        # 去掉开头和结尾的(反)斜杠
        filename = self.__check_ymlfile_name(filepathname)
        print("filename is ---------", filename)
        py_str = ".py"
        yml_str = ".yml"
        # 为了防止将yml文件写成了py文件,所以要先将py文件替换为yml文件
        # 因为casee yml文件的名称与case py文件的名称是一致的.
        if filename.endswith(py_str):
            exp = f"({py_str})$"
            filename = re.sub(exp, yml_str, filename)
        # 检查文件后缀
        filename = filename if filename.endswith(yml_str) else filename + yml_str
        # 拼接文件路径
        filepath = os.path.abspath(os.path.join(self.__ymlfilepath, filename))
        return filepath

    def get_file_abspath_json(self, filepathname: str):
        """
        1:拼接json文件的绝对路径
        2:filepathname: json文件的名称，包括路径。但不包含jsonfile所在的目录。如 jsonfile/test_data.json，而不是jsonfile/demo/test_data.json
        3:在检测filepathname时，当以/ 或 \\ 开头或结尾时，则直接去掉这些 / 或\\
        4:然后再检测filename 是否以 yml文件的顶层目录，如jsonfile进行开头，如 jsonfile/ 或 jsonfile\\
        5:当以 yml文件的顶层目录进行开头时，则直接去掉。因为在拼接时，会自动加上顶层目录。
        6:对拼接后的结果，文件是否存在，先不进行验证。
        """

        # 去掉开头和结尾的(反)斜杠
        filename = self.__check_jsonfile_name(filepathname)
        py_str = ".py"
        json_str = ".json"
        # 为了防止将yml文件写成了py文件,所以要先将py文件替换为yml文件
        # 因为casee yml文件的名称与case py文件的名称是一致的.
        if filename.endswith(py_str):
            exp = f"({py_str})$"
            filename = re.sub(exp, json_str, filename)
        # 检查文件后缀
        filename = filename if filename.endswith(json_str) else filename + json_str
        # 拼接文件路径
        filepath = os.path.abspath(os.path.join(self.__jsonfilepath, filename))
        return filepath

    def check_file_exists(self, filepathname: str) -> bool:
        """检测文件是否存在"""
        flag = os.path.exists(filepathname)
        return flag

    def check_tokenfile_available(self, login_type: str, filepathname: str) -> bool:
        """
        检测保存token的json文件是否可用.当文件存在的情况下,且json大小不为0,且在限制的session时长范围内,则表示有效  \n
        :param login_type: 登录类型,是web还是app.不同的端session限制不同
        :param filepathname: json文件路径
        :return: bool
        """
        login_type = login_type
        filepath = filepathname
        flag = False
        # 先检测文件是否存在
        flag = self.check_file_exists(filepath)
        if flag == False:
            return flag
        else:
            # 检测文件的大小
            file_attribute = os.stat(filepath)
            # 获取文件大小
            size = file_attribute.st_size
            # 获取文件的上次修改时间(返回的是时间戳)
            mtime = file_attribute.st_mtime

            if size == 0:
                flag = False
                return flag
            # 表示文件有值
            else:
                # 检测是否在session时长的有效范围内,需要注意的是配置文件里的时间是分钟,不是秒.
                from config.get_conf_data import GetConfData
                from common.util.handle_datetime import HandleDateTime
                conf = GetConfData()
                htime = HandleDateTime()
                app_str = conf.get_app_str()
                web_str = conf.get_web_str()
                if login_type == app_str:
                    app_session = conf.get_app_session_limit()
                    # 当为0时,表示session 时长没有限制.
                    if app_session == 0 or app_session == None:
                        flag = True

                    # 此时要检测时长
                    else:
                        # 将时间戳转化为时间字符串
                        mtime = htime.timestamp_to_time(mtime)
                        # 获取当前时间
                        cur_time = htime.get_curtime_to_ss()
                        # 计算两个时间的时间差
                        time_delta = htime.time_delta_mm(mtime,cur_time)
                        # 比较是否在session限制时间范围内
                        if time_delta < app_session:
                            flag = True
                        # 表示超过了时间限制
                        else:
                            flag = False
                    return flag

                # web端登录
                elif login_type == web_str:
                    web_session = conf.get_web_session_limit()
                    # 先判断是否有时间限制
                    if web_session == 0 or web_session == None:
                        flag = True

                    else:
                        # 将时间戳转化为时间字符串
                        mtime = htime.timestamp_to_time(mtime)
                        # 获取当前时间
                        cur_time = htime.get_curtime_to_ss()
                        # 计算两个时间的时间差
                        time_delta = htime.time_delta_mm(mtime, cur_time)
                        # 比较是否在session限制时间范围内
                        if time_delta < web_session:
                            flag = True
                        # 表示超过了时间限制
                        else:
                            flag = False
                    # 返回标志.
                    return flag


    def __check_ymlfile_name(self, filename: str):
        """检测filename 是否以(反)斜杠开头或结尾,如果有,则去掉"""
        return self.__check_filename("yml", filename)

    def __check_jsonfile_name(self, filename: str):
        """检测filename 是否以(反)斜杠开头或结尾,如果有,则去掉"""
        return self.__check_filename("json", filename)

    def __check_filename(self, flag: str, filename: str):
        """
        检测filename 是否以(反)斜杠开头或结尾,如果有,则去掉
        检测filename 里是否包含了yml文件或json文件的顶层目录,如ymlfile 或 jsonfile
        当检测到时,就会去掉.
        """
        filename = filename.strip(self.__slash).strip(self.__backslash)
        dirname = ""
        if flag == "json":
            dirname = self.__jsonfilename
        elif flag == "yml":
            dirname = self.__ymldirname

        slash_dir = f'{dirname}{self.__slash}'
        backslash_dir = f'{dirname}{self.__backslash}'
        if filename.startswith(slash_dir):
            exp = f"^({slash_dir})"
            filename = re.sub(exp, "", filename)
        elif filename.startswith(backslash_dir):
            exp = f"^({backslash_dir}\\)"
            filename = re.sub(exp, "", filename)

        return filename
